Declaration of reference variables (incl. assignments to them)

Syntax
VAR | VAR_INPUT | VAR_OUTPUT | VAR_TEMP
   name_1, name_2, ..., name_n : REF_TO type [:= REF(name_A)];
   name_3, name_4, ..., name_n : REF_TO ARRAY [x..y] OF type [:= REF(name_B)];   (* Up to 4 dimensions are possible. *)
   ...
(* Additional pieces of data, such as partial addresses, are also possible for the variables. *)
END_VAR
Meaning

Declaration of one or more →reference variables, name_1, name_2 etc. must be →IEC-identifiers. You might have heard of "→pointers" instead of references.

As type for the reference variable, you are able to use a →data type, a →function block or a →Class. See "Supported data types" to learn which data types are supported.

Use the optional →initial value := REF(...) to assign the address of an already declared variable to the reference variable. This variable must be of the same data type as the reference. If you do not enter an initial value, the reference is initialized with value NULL (i.e., the reference refers to nothing).
As an enhancement to the →IEC-standard, it is also possible to directly declare a reference to an ARRAY – this is similar to the declaration of an array data type.

Current restrictions

  • It is not possible to use references as base for →derived data types.

  • It is not possible to use reference variables as base for array data types or array variables.

  • It is not possible to declare references to references.

  • It is not possible to declare references to constant variables.

  • It is not possible to declare references to →global variables with the attribute DMA.

  • References to an →interface or to a →function are not supported in Neuron Power Engineer.

  • Mind for the usage of REF(...):

    • →Temporary variables (= VAR_TEMP) are not allowed within REF(...).

    • The parameters for the execution control parameters EN and ENO are not allowed within REF(...).

    • Within →functions, only →external variables are allowed within REF(...) – if the rule References to local variables must not be used in functions/methods is activated.

    • References to →in-out variables are not allowed as an initial value for reference variables.

    • If an ARRAY reference variable is used within REF(...), the variable must be based on the same data type and the same index subrange as the reference variable to which the assignment is executed.

 

The declaration of reference variables is possible within these sections: 
(Consult the respective description of the section about possibly additional possibilities for the variable.)

Section

The declaration of the reference is done as:

VAR ... END_VAR

internal variable (see "Declaration of internal variables in ST")

VAR_INPUT ... END_VAR

input variable (see "Declaration of input variables in ST")

VAR_OUTPUT ... END_VAR

output variable (see "Declaration of output variables in ST")

VAR_TEMP ... END_VAR

temporary variable (see "Declaration of temporary variables in ST")

Example
VAR
   myInt: INT;
   myArray: ARRAY [1..10] OF INT;
  
   myRef: REF_TO INT := REF(myInt);
   myRefArr: REF_TO ARRAY [1..10] OF INT := REF(myArray);
   myRef2: REF_TO INT := REF(myArray[1]);
END_VAR

Assignments to reference variables

In general, →assignments to reference variables are possible within the declared language element. However, the usage of REF(...) is restricted (see the above restrictions).

Syntax
reference_variable_1 := REF(name) | NULL;
reference_variable_1 := reference_variable_2;

The expression on the right side of the assignment operator ":=" may be one of the following constructs:

  • REF(name)name must be a variable of the same data type as the reference variable to which the assignment is done – Mind the restrictions for the usage of REF() that are listed above.

  • NULL

  • another declared reference variable, if it is of the same data type as the reference variable to which the assignment is done
    If the assignment is done to an ARRAY reference variable, the variable must be based on the same data type and the same index subrange.

Example
VAR
  Int1R : REF_TO INT;
  Int2R : REF_TO INT;
  DIntR : REF_TO DINT;
  Int1  : INT;
  DInt2 : DINT;
 
  ArrIntR1 : REF_TO ARRAY [1..10] OF INT;
  ArrInt1  : ARRAY [1..10] OF INT;
  ArrInt2  : ARRAY [2..11] OF INT;
END_VAR
 
Int1R := NULL;             (* OK, because 'NULL' is allowed for assignment to a reference variable *)
Int1R := REF(Int1);        (* OK, because 'Int1' is of the same data type as 'Int1R' *)
Int1R := Int2R;            (* OK, because 'Int2R' is of the same data type as 'Int1R' *)
ArrIntR1 := REF(ArrInt1);  (* OK, because 'ArrInt1' is of the same data type and the same index subrange as 'ArrIntR1' *)
 
Int1R := 0;                (* error, because '0' is not allowed for assignment to a reference variable *)
Int1R := REF(DInt2);       (* error, because 'DInt2' is not of the same data type as 'Int1R' *)
Int1R := DIntR;            (* error, because 'DIntR' is not of the same data type as 'Int1R' *) 
Int1R := Int1;             (* error, because 'Int1' kis not a reference variable *)  
ArrIntR1 := REF(ArrInt2);  (* error, because 'ArrInt2' has not been declared with the same index subrange as 'ArrIntR1', although it is of the same data type *) 
ArrIntR1 := ArrInt2;       (* error, because 'ArrInt2' is not a reference variable *)

Dereferencing: Accessing the content of reference variables

Accessing the content of reference variables is known as dereferencing. This is done by the character ^ that follows the name of the reference variable.

Examples
Int1   := Int1R^;         (* The content of the variable to which the reference variable 'Int1R' references is assigned to the variable 'Int1'. *)
Int2R^ := ArrIntR1^[2];   (* Now the variable to which 'Int2R' references contains the same content as the 2nd element of the ARRAY variable to which the reference variable 'ArrIntR1' references. *)
ArrIntR1^ := ArrInt1;     (* The variable 'ArrInt1' is assigned to the content of the variable to which the reference variable 'ArrIntR1' references. *)

Access to reference variables with the content NULL

Neuron Power Engineer does not validate these ST-constructs when entered in the ST-editor but when the application is executed. In this case, the following error handling occurs:

  1. The output ENO of the embracing →POU is set to the value FALSE (or an equivalent).

  2. The remaining block code is not executed anymore.

In the above example, the assignment Int1 := Int1R^; is not executed, because the access is located on the right side of the assignment operator ":=".

Neuron recommends you to add code to your application (e.g. IF-statements) so that the usage of such variables with the content NULL is detected.